import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Dinic {
	private static final int INF = 0x3f3f3f3f;
	private static int n, m, s, t, net;
	private static ArrayList < ArrayList < Integer > > g;
	private static ArrayList < Edge > e;
	private static int[] d, q, ptr;
	
	public static void main(String []args) {
		InputReader in = new InputReader();
		PrintWriter out = new PrintWriter(System.out);
		n = in.nextInt();
		m = in.nextInt();
		d = new int[n + 1];
		q = new int[2 * n + 1];
		ptr = new int[n + 1];
		e = new ArrayList < Edge > (m);
		g = new ArrayList < ArrayList < Integer > > (n + 1);
		for (int i = 1; i <= n + 1; ++i) {
			g.add(new ArrayList < Integer > ());
		}
		for (int i = 0; i < m; ++i) {
			addEdge(in.nextInt(), in.nextInt(), in.nextInt());
		}
		s = 1;
		t = n;
		long ans = dinic();
		out.println(ans);
		out.close();
	}
	
	private static boolean bfs() {
		int qh = 0, qt = 0;
		q[qt++] = s;
		Arrays.fill(d, 1, n + 1, -1);
		d[s] = 0;
		while (qh < qt && d[t] == -1) {
			int v = q[qh++];
			for (int id : g.get(v)) {
				int to = e.get(id).b;
				if (d[to] == -1 && e.get(id).flow + net < e.get(id).cap) {
					q[qt++] = to;
					d[to] = d[v] + 1;
				}
			}
		}
		return (d[t] != -1); 
	}
	
	private static int dfs(int v, int flow) {
		if (flow == 0)
			return 0;
		if (v == t)
			return flow;
		for (; ptr[v] < g.get(v).size(); ++ptr[v]) {
			int id = g.get(v).get(ptr[v]),
				to = e.get(id).b;
			if (d[to] != d[v] + 1)
				continue;
			int pushed = dfs(to, Math.min(flow, e.get(id).cap - e.get(id).flow));
			if (pushed != 0) {
				e.get(id).flow += pushed;
				e.get(id ^ 1).flow -= pushed;
				return pushed;
			}
		}
		return 0;
	}
	
	private static long dinic() {
		long flow = 0L;
		net = 1000000000;
		do {
			net >>= 1;
			for (;;) {
				if (!bfs())
					break;
				Arrays.fill(ptr, 1, n + 1, 0);
				int pushed = dfs(s, INF);
				while (pushed != 0) {
					flow += pushed;
					pushed = dfs(s, INF);
				}
			}
		} while (net != 0);
		return flow;
	}
	
	private static void addEdge(int a, int b, int cap) {
		g.get(a).add(e.size());
		e.add(new Edge(a, b, cap));
		g.get(b).add(e.size());
		e.add(new Edge(b, a, 0));
	}
}

class Edge {
	public int a, b, cap, flow;
	
	public Edge() {
		this(0, 0, 0);
	}
	
	public Edge(int _a, int _b, int _cap) {
		a = _a;
		b = _b;
		cap = _cap;
		flow = 0;
	}
}

class InputReader {
	public BufferedReader reader;
	public StringTokenizer tokenizer;
	
	public InputReader() {
		reader = new BufferedReader(new InputStreamReader(System.in));
		tokenizer = null;
	}
	
	public String nextString() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}
	
	public int nextInt() {
		return Integer.parseInt(nextString());
	}
}
